package restaurant.selector.gui;

import java.io.IOException;

import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.layout.FormAttachment;
import org.eclipse.swt.layout.FormData;
import org.eclipse.swt.layout.FormLayout;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.layout.RowLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.List;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.swt.widgets.MenuItem;
import org.eclipse.swt.widgets.Monitor;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;

import restaurant.selector.Configuration;
import restaurant.selector.Restaurant;
import restaurant.selector.User;
import restaurant.selector.database.DatabaseManager;
import restaurant.selector.logic.LogicFactory;
import restaurant.selector.logic.LogicInterface;

public class GuiMain implements Listener {
	
	private Shell shell;
	private MenuItem exit, connect, addRestaurant, delRestaurant, addUser, delUser;
	private Combo weather;
	private Button quick;
	private Button doIt;
	private Text todaysLunch;
	
	private DatabaseManager databaseManager = DatabaseManager.getInstance();
	private LogicInterface logic;
	
	public GuiMain() throws IOException{
		
		// Set up the Non-GUI parts of this application
		Configuration configuration = Configuration.getInstance();
		configuration.init( "config.properties" );
		
		databaseManager.init(configuration.getDatabaseDriver(),
				configuration.getDatabaseUser(),
				configuration.getDatabasePassword(),
				configuration.getDatabaseUrl(),
				configuration.getDatabaseStore());

		LogicFactory logicFactory = LogicFactory.getInstance();
		logic = logicFactory.getLogic(configuration.getDatabaseLogic(), databaseManager);
		
		
		Display display = new Display();
		shell = new Shell(display);
		
		shell.setLayout(new FormLayout());
		
		createMenuBar(shell);
		
		//Fill Layout panel
		Composite fillComp = new Composite(shell, SWT.BORDER);
		fillComp.setLayout(new FillLayout(SWT.VERTICAL));
		final List restaurantList = new List (fillComp, SWT.BORDER | SWT.MULTI | SWT.V_SCROLL);
		java.util.List<Restaurant> restaurants = databaseManager.getRestaurants();
		for( Restaurant r : restaurants ){
			restaurantList.add( r.getName() );
		}
		
		restaurantList.addListener (SWT.Selection, new Listener () {
			public void handleEvent (Event e) {
				String string = "";
				int [] selection = restaurantList.getSelectionIndices ();
				for (int i=0; i<selection.length; i++) string += selection [i] + " ";
				System.out.println ("Selection={" + string + "}");
			}
		});
		
		FormData formFill = new FormData();
		formFill.top = new FormAttachment(0, 10);
		formFill.left = new FormAttachment(0, 10);
		formFill.bottom = new FormAttachment(75, 0);
		formFill.right = new FormAttachment(40,0);
		fillComp.setLayoutData(formFill);

		//Row Layout panel
		Composite rowComp = new Composite(shell, SWT.NONE);
		RowLayout rowLayout = new RowLayout();
		rowLayout.pack = false;
		rowComp.setLayout(rowLayout);
		doIt = new Button(rowComp, SWT.PUSH);
		doIt.setText("Do IT");
		doIt.addListener(SWT.Selection, this);

		FormData formRow = new FormData();
		formRow.top = new FormAttachment(fillComp, 10);
		formRow.left = new FormAttachment(0, 10);
		formRow.bottom = new FormAttachment(100, -10);
		formRow.right = new FormAttachment(100, -10);
		rowComp.setLayoutData(formRow);

		//Grid Layout panel
		Composite gridComp = new Composite(shell, SWT.NONE);
		GridLayout gridLayout = new GridLayout();
		gridLayout.numColumns = 1;
		gridComp.setLayout(gridLayout);
		
		GridData data = new GridData();
		
		List userList = new List (gridComp, SWT.BORDER | SWT.MULTI | SWT.V_SCROLL);
		java.util.List<User> users = databaseManager.getUsers();
		for( User u : users )
			userList.add( u.getName() );
		data.widthHint = 200;
		userList.setLayoutData(data);
		
		Composite optionsPanel = new Composite(gridComp, SWT.BORDER);
		optionsPanel.setSize(400, 400);
		GridLayout optionsPanelLayout = new GridLayout();
		optionsPanelLayout.numColumns = 1;
		optionsPanel.setLayout(optionsPanelLayout);
		
		
		Label optionsLabel = new Label(optionsPanel, SWT.NONE);
		data = new GridData(GridData.FILL_HORIZONTAL);
		optionsLabel.setText("Weather :");
		optionsLabel.setLayoutData(data);
		
		weather = new Combo (optionsPanel, SWT.READ_ONLY);
		weather.setItems (new String [] {"OK", "Rain", "Snow", "Cold"});
		weather.select(0);
		data = new GridData();
		data.widthHint = 150;
		weather.setLayoutData(data);
		
		quick = new Button(optionsPanel, SWT.CHECK);
		quick.setText("Quick Lunch?");
		quick.addListener(SWT.Selection, this);
		data = new GridData(GridData.FILL_HORIZONTAL);
		quick.setLayoutData(data);
		
		Label todaysLunchLabel = new Label(optionsPanel, SWT.NONE);
		todaysLunchLabel.setText("Today's Lunch : ");
		data = new GridData();
		data.widthHint = 150;
		todaysLunchLabel.setLayoutData(data);
		
		todaysLunch = new Text(optionsPanel, SWT.NONE);
		todaysLunch.setEditable(false);
		todaysLunch.setTextLimit(20);
		data = new GridData(GridData.FILL_HORIZONTAL);
		data.widthHint = 200;
		todaysLunch.setLayoutData(data);
		
		FormData formGrid = new FormData();
		formGrid.top = new FormAttachment(0,10);
		formGrid.left = new FormAttachment(fillComp,10);
		formGrid.right = new FormAttachment(100,-10);
		formGrid.bottom = new FormAttachment(fillComp,10, SWT.BOTTOM);
		gridComp.setLayoutData(formGrid);
		
		shell.setSize(500, 600);
		
		Monitor primary = display.getPrimaryMonitor ();
		Rectangle bounds = primary.getBounds ();
		Rectangle rect = shell.getBounds ();
		int x = bounds.x + (bounds.width - rect.width) / 2;
		int y = bounds.y + (bounds.height - rect.height) / 2;
		shell.setLocation (x, y);

		shell.open ();

		while (!shell.isDisposed ()) {
			if (!display.readAndDispatch ())
				display.sleep ();
		}
		display.dispose ();
	}
	
	private void createMenuBar( Shell shell ){
		
		Menu bar = new Menu (shell, SWT.BAR);
		shell.setMenuBar (bar);
		
		Menu fileMenu = new Menu(shell, SWT.DROP_DOWN);
		MenuItem fileItem = new MenuItem(bar, SWT.CASCADE);
		fileItem.setText("&File");
		fileItem.setMenu(fileMenu);
		exit = createMenuItem(fileMenu, "&Exit");
		
		Menu dbMenu = new Menu(shell, SWT.DROP_DOWN);
		MenuItem dbItem = new MenuItem(bar, SWT.CASCADE);
		dbItem.setText("&Database");
		dbItem.setMenu(dbMenu);
		connect = createMenuItem(dbMenu, "&Connect");
		
		Menu adminMenu = new Menu(shell, SWT.DROP_DOWN );
		MenuItem adminItem = new MenuItem(bar, SWT.CASCADE);
		adminItem.setText("&Admin");
		adminItem.setMenu(adminMenu);
		addRestaurant = createMenuItem(adminMenu, "Add Restaurant");
		delRestaurant = createMenuItem(adminMenu, "Delete Restaurant");
		addUser = createMenuItem(adminMenu, "Add User");
		delUser = createMenuItem(adminMenu, "Delete Restaurant");
	}
	
	private MenuItem createMenuItem( Menu menu, String text ){
		MenuItem menuItem = new MenuItem(menu, SWT.PUSH);
		menuItem.setText(text);
		menuItem.addListener(SWT.Selection, this);
		return menuItem;
	}
	
	@Override
	public void handleEvent(Event event) {
		
		if( event.widget == exit ){
			System.exit(0);
		} else if( event.widget == connect ){
			System.out.println("CONNECT");
		} else if( event.widget == doIt ){
			todaysLunch.setText( logic.getRestaurant() );
		} else if( event.widget == addUser ){
			AddUserShell aus = new AddUserShell(shell);
			aus.open();
			if( aus.getUsername() != null ){
				databaseManager.addUser( aus.getUsername() );
			}
		} else if( event.widget == addRestaurant ){
			AddRestaurantShell ars = new AddRestaurantShell(shell);
			ars.open();
			
			if( ars.getName() != null ){
				databaseManager.addRestaurant(ars.getName(), 
						ars.isQuick(), ars.getDistance());
			}
		}
	}

	public static void main(String[] args) throws IOException {
		
		new GuiMain();
	}
}
